package activity.study.initmysql.test;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.Task;
import org.activiti.bpmn.model.UserTask;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import java.io.ByteArrayInputStream;
import java.util.List;

@SpringBootTest
//@RunWith(SpringRunner.class)
public class T {
    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    // 部署流程定义
    /*@Test
    public void deploy() {
        try {
            Deployment deployment = repositoryService.createDeployment() // 创建部署
                    .addClasspathResource("bpmnfile/csdn-variable.bpmn20.xml") // 加载流程资源文件
                    .name("测试任务退回111") // 流程名称
                    .deploy(); // 部署
            System.out.println("流程部署ID:" + deployment.getId());
            System.out.println("流程部署Name:" + deployment.getName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }*/

    @Test
    public void deploy() {
        Deployment deployment = repositoryService.createDeployment() // 创建部署
//                .addClasspathResource("bpmnfile/csdn-variable.bpmn20.xml") // 加载流程资源文件
                .addClasspathResource("bpmnfile/askforleave.bpmn20.xml") // 加载流程资源文件
                .name("我妹妹结婚，请个假回家111") // 流程名称
                .deploy(); // 部署
    /*
    流程部署ID:57501
    流程部署Name:helloworld流程
    */
        System.out.println("流程部署ID:" + deployment.getId());
        System.out.println("流程部署Name:" + deployment.getName());
    }


    // 创建模型
    @Test
    public void createModel() {
        Model model = repositoryService.newModel();
        model.setName("预催收ivr-快还我钱");
        model.setKey("ycssss");
        model.setMetaInfo("{somejson}");

        repositoryService.saveModel(model);

        String id = model.getId();

        System.out.println("id: " + id);
    }

    // 更新模型
    @Test
    public void updateModel() {
        /*Model model = repositoryService.newModel();
        model.setName("预催收ivr");
        model.setKey("ycs");
        model.setMetaInfo("{somejson}");

        repositoryService.saveModel(model);

        String id = model.getId();

        System.out.println("id: " + id);*/

        final Model model = repositoryService.getModel("8799ed78-b14b-11ef-9a78-989096ca675d");


        System.out.println(model.getName());

        model.setDeploymentId("25cd11c6-b149-11ef-8f65-989096ca675d");

        repositoryService.saveModel(model);
    }

    // 保存流程设计source
    @Test
    public void addModelEditorSource() throws Exception {
        String modelId = "3778686f-b1f0-11ef-af14-989096ca675d";
        // model id 正常由前端给出
//        final Model model = repositoryService.getModel(modelId);

        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<definitions xmlns=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:activiti=\"http://activiti.org/bpmn\" xmlns:bpmndi=\"http://www.omg.org/spec/BPMN/20100524/DI\" xmlns:omgdc=\"http://www.omg.org/spec/DD/20100524/DC\" xmlns:omgdi=\"http://www.omg.org/spec/DD/20100524/DI\" typeLanguage=\"http://www.w3.org/2001/XMLSchema\" expressionLanguage=\"http://www.w3.org/1999/XPath\" targetNamespace=\"http://www.activiti.org/test\">\n" +
                "    <process id=\"askForLeave\" name=\"askForLeave\" isExecutable=\"true\">\n" +
                "        <startEvent id=\"startevent1\" name=\"Start\"></startEvent>\n" +
                "        <endEvent id=\"endevent1\" name=\"End\"></endEvent>\n" +
                "        <userTask id=\"usertask1\" name=\"请假了\" activiti:assignee=\"散散\"></userTask>\n" +
                "        <sequenceFlow id=\"flow1\" sourceRef=\"startevent1\" targetRef=\"usertask1\"></sequenceFlow>\n" +
                "        <sequenceFlow id=\"flow2\" sourceRef=\"usertask1\" targetRef=\"endevent1\"></sequenceFlow>\n" +
                "    </process>\n" +
                "    <bpmndi:BPMNDiagram id=\"BPMNDiagram_askForLeave\">\n" +
                "        <bpmndi:BPMNPlane bpmnElement=\"askForLeave\" id=\"BPMNPlane_askForLeave\">\n" +
                "            <bpmndi:BPMNShape bpmnElement=\"startevent1\" id=\"BPMNShape_startevent1\">\n" +
                "                <omgdc:Bounds height=\"35.0\" width=\"35.0\" x=\"260.0\" y=\"121.0\"></omgdc:Bounds>\n" +
                "            </bpmndi:BPMNShape>\n" +
                "            <bpmndi:BPMNShape bpmnElement=\"endevent1\" id=\"BPMNShape_endevent1\">\n" +
                "                <omgdc:Bounds height=\"35.0\" width=\"35.0\" x=\"270.0\" y=\"340.0\"></omgdc:Bounds>\n" +
                "            </bpmndi:BPMNShape>\n" +
                "            <bpmndi:BPMNShape bpmnElement=\"usertask1\" id=\"BPMNShape_usertask1\">\n" +
                "                <omgdc:Bounds height=\"55.0\" width=\"105.0\" x=\"235.0\" y=\"231.0\"></omgdc:Bounds>\n" +
                "            </bpmndi:BPMNShape>\n" +
                "            <bpmndi:BPMNEdge bpmnElement=\"flow1\" id=\"BPMNEdge_flow1\">\n" +
                "                <omgdi:waypoint x=\"277.0\" y=\"156.0\"></omgdi:waypoint>\n" +
                "                <omgdi:waypoint x=\"287.0\" y=\"231.0\"></omgdi:waypoint>\n" +
                "            </bpmndi:BPMNEdge>\n" +
                "            <bpmndi:BPMNEdge bpmnElement=\"flow2\" id=\"BPMNEdge_flow2\">\n" +
                "                <omgdi:waypoint x=\"287.0\" y=\"286.0\"></omgdi:waypoint>\n" +
                "                <omgdi:waypoint x=\"287.0\" y=\"340.0\"></omgdi:waypoint>\n" +
                "            </bpmndi:BPMNEdge>\n" +
                "        </bpmndi:BPMNPlane>\n" +
                "    </bpmndi:BPMNDiagram>\n" +
                "</definitions>";
        repositoryService.addModelEditorSource(modelId, xml.getBytes("UTF-8"));

    }

    @Test
    public void deployModel() {
        try {
            String modelId = "3778686f-b1f0-11ef-af14-989096ca675d";

            Model modelData = repositoryService.getModel(modelId);
//            ObjectNode modelNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
//            byte[] bpmnBytes = null;
//
//            BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
//            bpmnBytes = new BpmnXMLConverter().convertToXML(model);
//
//            String processName = modelData.getName() + ".bpmn20.xml";
            byte[] bpmnBytes = repositoryService.getModelEditorSource(modelData.getId());
            // 注意：addString的resourceName必须以.bpmn20.xml结尾，不然不会生成流程定义，应该是bug
            Deployment deployment = repositoryService.createDeployment().name(modelData.getName()).addString("askforleave.bpmn20.xml", new String(bpmnBytes, "UTF-8")).deploy();
            final String deploymentId = deployment.getId();
            System.out.println("部署成功，部署ID=" + deploymentId);
            System.out.println("更新到部署信息到模型，这样就可以从模型发起一路关联下去了，不然就断掉啦！");
            modelData.setDeploymentId(deploymentId);

            repositoryService.saveModel(modelData);
        } catch (Exception e) {
//            LOGGER.error("根据模型部署流程失败：modelId={}", modelId, e);
            e.printStackTrace();
        }

    }

    @Test
    public void deployModelHuoHuo() {
        try {
            String modelId = "3778686f-b1f0-11ef-af14-989096ca675d";

            Model modelData = repositoryService.getModel(modelId);
//            ObjectNode modelNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
            byte[] bpmnXmlBytes = null;

            bpmnXmlBytes = repositoryService.getModelEditorSource(modelData.getId());


            XMLStreamReader xmlReader = XMLInputFactory.newFactory().createXMLStreamReader(new ByteArrayInputStream(bpmnXmlBytes));
//
//            XMLStreamReader xmlStreamReader = new Xm
//            BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
            BpmnModel model = new BpmnXMLConverter().convertToBpmnModel(xmlReader);
            final Process mainProcess = model.getMainProcess();
            final List<UserTask> flowElementsOfType = mainProcess.findFlowElementsOfType(UserTask.class);
            for (UserTask userTask : flowElementsOfType) {
                System.out.println(userTask);
            }
//            bpmnBytes = new BpmnXMLConverter().convertToXML(model);
//
//            String processName = modelData.getName() + ".bpmn20.xml";
/*
            byte[] bpmnBytes = repositoryService.getModelEditorSource(modelData.getId());
            // 注意：addString的resourceName必须以.bpmn20.xml结尾，不然不会生成流程定义，应该是bug
            Deployment deployment = repositoryService.createDeployment().name(modelData.getName()).addString("askforleave.bpmn20.xml", new String(bpmnBytes, "UTF-8")).deploy();
            final String deploymentId = deployment.getId();
            System.out.println("部署成功，部署ID=" + deploymentId);
            System.out.println("更新到部署信息到模型，这样就可以从模型发起一路关联下去了，不然就断掉啦！");
            modelData.setDeploymentId(deploymentId);

            repositoryService.saveModel(modelData);
*/
        } catch (Exception e) {
//            LOGGER.error("根据模型部署流程失败：modelId={}", modelId, e);
            e.printStackTrace();
        }

    }

    @Test
    public void getProcessList() {
        try {
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

            List<ProcessDefinition> pdList = processEngine.getRepositoryService() // 获取service类
                    .createProcessDefinitionQuery() // 创建流程定义查询
//                    .processDefinitionKey("helloWorldProcess") // 通过key查询
                    .list(); // 返回一个集合
            for (ProcessDefinition pd : pdList) {
                System.out.println("ID_：" + pd.getId());
                System.out.println("NAME_：" + pd.getName());
                System.out.println("KEY_：" + pd.getKey());
                System.out.println("VERSION_：" + pd.getVersion());
                System.out.println("===================");
            }
        } catch (Exception e) {
//            LOGGER.error("根据模型部署流程失败：modelId={}", modelId, e);
            e.printStackTrace();
        }

    }

    // askForLeave
    @Test
    public void startProcessInst() {
        try {
            String processDefKey = "askForLeave";
//            ProcessInstance pi = runtimeService.startProcessInstanceByKey("csdnvariable"); // 流程定义表的KEY字段值
            ProcessInstance pi = runtimeService.startProcessInstanceByKey(processDefKey); // 流程定义表的KEY字段值
            System.out.println("流程实例ID:" + pi.getId());
            System.out.println("流程定义ID:" + pi.getProcessDefinitionId());
        } catch (Exception e) {
//            LOGGER.error("根据模型部署流程失败：modelId={}", modelId, e);
            e.printStackTrace();
        }
    }

    @Autowired
    private TaskService taskService;

    @Test
    public void queryTaskAndComplete() {
        try {

            String userId = "散散";
            List<org.activiti.engine.task.Task> taskList = taskService.createTaskQuery()
//                    .processDefinitionKey("activiti_leave")
                    .taskAssignee(userId)
                    .orderByTaskCreateTime()
                    .desc()
                    .list();

            for(org.activiti.engine.task.Task task: taskList){
                System.out.println("任务id: "+task.getId());
                System.out.println("任务名字: "+task.getName());
                System.out.println("任务创建时间: "+task.getCreateTime());
                System.out.println("办理人: "+task.getAssignee());

                // 完成任务
                taskService.complete(task.getId());
            }
        } catch (Exception e) {
//            LOGGER.error("根据模型部署流程失败：modelId={}", modelId, e);
            e.printStackTrace();
        }
    }
}
